package com.bndg.blackjack.services

import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Binder
import android.os.IBinder
import android.util.Log
import com.bndg.blackjack.AppUtils
import com.xuhao.didi.core.iocore.interfaces.IIOCoreOptions
import com.xuhao.didi.core.iocore.interfaces.ISendable
import com.xuhao.didi.core.pojo.OriginalData
import com.xuhao.didi.socket.client.sdk.OkSocket
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IClient
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IClientIOCallback
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IClientPool
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IServerActionListener
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IServerManager
import com.xuhao.didi.socket.common.interfaces.common_interfacies.server.IServerShutdown
import com.xuhao.didi.socket.server.action.ServerActionAdapter
import java.nio.charset.Charset

/**
 * @author r
 * @date 2024/12/9
 * @description 服务端
 */
class ServerService : BaseService(), IClientIOCallback, IServerActionListener {
    private val mPort = 8080
    private var mServerManager: IServerManager<IIOCoreOptions>? = null

    companion object {
        fun bind(context: Context, serviceConnection: ServiceConnection, flag: Int) {
            val intent = Intent(context, ServerService::class.java)
            context.bindService(intent, serviceConnection, flag)
        }
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Log.d(">>>>", "onStartCommand: ")
        return super.onStartCommand(intent, flags, startId)
    }

    override fun onDestroy() {
        super.onDestroy()
        Log.d(">>>>", "stop: service")
        OkSocket.server(mPort).unRegisterReceiver(this@ServerService)
        mServerManager?.let {
            if (it.isLive) {
                it.shutdown()
            }
        }
    }

    inner class ServerBinder : Binder() {
        fun getService(): ServerService {
            return this@ServerService
        }
    }

    private var mBinder = ServerBinder()
    override fun onBind(p0: Intent?): IBinder {
        Log.d(">>>>", "onBind: server")
        initServer()
        return mBinder
    }

    private fun initServer() {
        mServerManager = OkSocket.server(mPort).registerReceiver(this@ServerService)
    }

    /**
     * 接收到客户端发送过来的消息
     */
    override fun onClientRead(
        originalData: OriginalData?,
        client: IClient?,
        clientPool: IClientPool<IClient, String>?
    ) {
        val str = String(originalData!!.bodyBytes, Charset.forName("utf-8"))
        Log.d(">>>>", "read : $str")
        dataCallback?.onReceived(str)
    }

    /**
     * 发送消息
     */
    override fun onClientWrite(
        sendable: ISendable?,
        client: IClient?,
        clientPool: IClientPool<IClient, String>?
    ) {

    }

    override fun sentMsg(data: String) {
        val msgDataBean = MsgDataBean(data)
        mServerManager?.clientPool?.sendToAll(msgDataBean)
    }

    fun startListen() {
        val ipAddress = AppUtils.getLocalIpAddress(applicationContext)
        Log.d(">>>>", "ipaddr: $ipAddress")
        if(ipAddress.isNotEmpty()) {
            mServerManager?.let {
                if (!it.isLive) {
                    Log.d(">>>>", "listen: 8080")
                    it.listen()
                }
            }
        }
    }

        override fun onServerListening(serverPort: Int) {
            Log.d(
                ">>>>",
                Thread.currentThread().name + " onServerListening,serverPort:" + serverPort
            )
            // 服务端已准备好
            dataCallback?.onServerListening(AppUtils.getLocalIpAddress(applicationContext), serverPort)
        }

        override fun onClientConnected(
            client: IClient,
            serverPort: Int,
            clientPool: IClientPool<*, *>
        ) {
            Log.d(
                ">>>>",
                Thread.currentThread().name + " onClientConnected,serverPort:" + serverPort + "--ClientNums:" + clientPool.size() + "--ClientTag:" + client.uniqueTag
            )
            client.addIOCallback(this@ServerService)
            // 需要提示客户端 有连接过来了
            dataCallback?.onClientConnected()
        }

        override fun onClientDisconnected(
            client: IClient,
            serverPort: Int,
            clientPool: IClientPool<*, *>
        ) {
            Log.d(
                ">>>>",
                Thread.currentThread().name + " onClientDisconnected,serverPort:" + serverPort + "--ClientNums:" + clientPool.size() + "--ClientTag:" + client.uniqueTag
            )
            client.removeIOCallback(this@ServerService)
        }

        override fun onServerWillBeShutdown(
            serverPort: Int,
            shutdown: IServerShutdown,
            clientPool: IClientPool<*, *>,
            throwable: Throwable
        ) {
            Log.d(
                ">>>>",
                Thread.currentThread().name + " onServerWillBeShutdown,serverPort:" + serverPort + "--ClientNums:" + clientPool
                    .size()
            )
            shutdown.shutdown()
        }

        override fun onServerAlreadyShutdown(serverPort: Int) {
            Log.d(
                ">>>>",
                Thread.currentThread().name + " onServerAlreadyShutdown,serverPort:" + serverPort
            )
        }
}